home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fritz: All Fritz
/
All Fritz.zip
/
All Fritz
/
FILES
/
UTILREEN
/
ZENO21.LZH
/
ZENO21.ASM
next >
Wrap
Assembly Source File
|
1989-01-23
|
19KB
|
548 lines
page ,132
; X:0
;
; ZENO: June 11, 1986
;
; Modified Sept 4, 1986 by R Tansky to fix 40-character mode
; Modified Oct 31, 1986 by R Tansky to further fix 40-character mode
; and to fix graphics mode
; Modified Jan 28, 1987 by C Blum to add code to support TTY mode
; call ( AH=0EH ). Required by some clone BIOS implementations
; ( DTK / ERSO for one ) because they do not issue any 'set
; cursor' calls from within the TTY mode call. This causes
; ZENO to lose its video offset and the display goes out to
; lunch.
; Modified May 29, 1987 by Lynn Ransdell to support KEDIT 3.51
; Modified Dec 13, 1988 by Glenn K. Smith to do snow checking
; and to add a /S option to enable this checking. This
; causes ZENO to be around 2 1/2 times slower. (ZENOTEST=66 @10mhz)
; Modified Jan 15, 1988 by Glenn K. Smith to speed up snow checking
; and to fix a bug. Some programs didn't work right with
; ZENO. Mainly those which modified the cursor position without
; calling ZENO. (Procomm+, Turbo Pascal CRT unit and others).
; The fix required calculating the screen offset using the BIOS
; cursor everytime a character was placed on the screen.
; (ZENOTEST now takes 46 seconds @10mhz. A 20 second savings)
;
;
cseg segment para public 'code'
zeno proc far
assume cs:cseg, ds:cseg, es:cseg, ss:cseg
org 100h ; for .COM file
;
environment equ 2Ch
command equ 80h
slashk equ 'K/'
slashk2 equ 'k/'
slashs equ 'S/'
slashs2 equ 's/'
;
;-------------------------------
; enter here on initial load
;-------------------------------
;
start:
;
jmp near ptr load_pgm
;
video_vector dd 0
core_seg dw 0
;
bios_cursor_posn label dword
bios_ofst dw 00h ; offset for active page
dw 40h ; segment for bios data
;
crt_mode db 2 ; passes if 4, 5, or 6
active_page db 0
cursor_type dw 0B0Ch ; DOS cursor
;
video_posn label dword
video_ofst dw 0 ; offset against video_seg
video_seg dw 0
;
video_addr dw 0
;
onesixty db 160
;
flag db 0 ; Snow checking flag
;
;-------------------------------
; enter here from int 10h
;-------------------------------
;
video_int:
sti ; interrupts on
pushf ; save flags
cmp cs:crt_mode,3 ; check for color text 1
je video_keep ; go if so
cmp cs:crt_mode,2 ; check for color text 2
je video_keep ; go if so
cmp cs:crt_mode,7 ; check for b/w
je video_keep ; go if so
cmp ah,0 ; to set mode
je route_set_mode
jmp video_exit ; go if graphics / 40 col
video_keep:
cmp ah,14 ; to write as TTY
je route_TTY
cmp ah,2 ; to set cursor
je route_set_cursor
cmp ah,10 ; to write char only
je write_char
cmp ah,9 ; to write char/attr
je route_write_both
cmp ah,3 ; to read cursor
je route_read_cursor
cmp ah,1 ; to set type
je route_set_type
cmp ah,0 ; to set mode
je route_set_mode
cmp ah,5 ; to set page
je route_set_page
cmp ax,0FEFEh ; kill code (FORMERLY 0FFOOh)
je route_do_kill ; go if found
video_exit:
popf ; restore flags
jmp cs:dword ptr video_vector ; hand off interrupt
;
route_TTY:
jmp TTY
;
route_write_both:
jmp write_both
;
route_read_cursor:
jmp read_cursor
;
route_set_page:
jmp set_page
;
route_set_type:
jmp set_type
;
route_set_cursor:
jmp set_cursor
;
route_set_mode:
jmp set_mode
;
route_do_kill:
jmp do_kill
;
write_char:
cmp bh,cs:active_page ; check page
jne video_exit ; pass to bios
cmp cx,1 ; for multiple write
jne video_exit ; pass to bios
push di ; save
push es ; save
push ax
les di,cs:bios_cursor_posn
mov ax,es:[di]
mov cx,ax ; copy posn
mov al,ah ; rows in al
mul cs:onesixty ; for bytes
xor ch,ch ; cols in cx
shl cx,1 ; for video
add ax,cx ; offset in ax
mov cs:video_ofst,ax ; store offset
pop ax
les di,cs:video_posn ; get screen position
cmp cs:flag,1
je writ0
stosb
jmp writ3
writ0: push dx ; Put char without snow
mov dx,03DAh
xchg ah,al ; Save char in AH for later use
cli
WaitNoH:
in al, dx ; Get 6845 Status
test al,8 ; Check vert retrace
jnz WaitE ; In Progress? go
rcr al,1 ; Wait for end of
jc WaitNoH ; horizontial retrace
WaitH:
in al, dx ; Get 6845 status again
rcr al, 1 ; Wait for horizontial
jnc WaitH ; retrace
WaitE:
xchg ah,al
stosb
sti
pop dx ; restore
writ3:
pop es ; restore
pop di ; restore
popf ; restore flags
iret ; done
;
set_cursor:
cmp bh,cs:active_page ; check page
jne video_exit ; pass to bios
push ax ; save
push cx ; save
push dx ; save
push di ; save
push es ; save
set_cursor_2:
add cs:video_ofst,2 ; for next char
les di,cs:bios_cursor_posn ; get bios
inc byte ptr es:[di] ; assume next
cmp es:[di],dx ; check if next
je offset_ready ; go if next
mov ax,dx ; get req posn
mov es:[di],ax ; save req posn
mov cx,ax ; copy posn
mov al,ah ; rows in al
mul cs:onesixty ; for bytes
xor ch,ch ; cols in cx
shl cx,1 ; for video
add ax,cx ; offset in ax
mov cs:video_ofst,ax ; store offset
offset_ready:
mov cx,cs:video_ofst ; offset in cx
shr cx,1 ; for byte count
mov ah,14 ; cursor MSB register
mov dx,cs:video_addr ; 6845 index addr
mov al,ah ; get register
out dx,al ; send register
inc dx ; 6845 data addr
mov al,ch ; get cursor MSB
out dx,al ; send cursor MSB
dec dx ; 6845 index addr
mov al,ah ; cursor MSB register
inc al ; cursor LSB register
out dx,al ; send register
inc dx ; 6845 data addr
mov al,cl ; get cursor LSB
out dx,al ; send cursor LSB
pop es ; restore
pop di ; restore
pop dx ; restore
pop cx ; restore
pop ax ; restore
popf ; restore flags
iret ; done
;
write_both:
cmp bh,cs:active_page ; check page
jne route_video_exit ; pass to bios
cmp cx,1 ; check multiple write
jne route_video_exit ; pass to bios
push ax ; save
push di ; save
push es ; save
mov ah,bl ; get attribute
push ax
les di,cs:bios_cursor_posn
mov ax,es:[di]
mov cx,ax ; copy posn
mov al,ah ; rows in al
mul cs:onesixty ; for bytes
xor ch,ch ; cols in cx
shl cx,1 ; for video
add ax,cx ; offset in ax
mov cs:video_ofst,ax ; store offset
pop ax
les di,cs:video_posn ; get screen position
cmp cs:flag,1 ; Snow checking?
je col
stosw ; Place char+attr onto screen
jmp col2
col: push dx
push bx
color: mov dx,03DAh
mov bx,ax
cli
WaitNoH1:
in al, dx ; Get 6845 Status
test al,8 ; Check vert retrace
jnz WaitE1 ; In Progress? go
rcr al,1 ; Wait for end of
jc WaitNoH1 ; horizontial retrace
WaitH1:
in al, dx ; Get 6845 status again
rcr al, 1 ; Wait for horizontial
jnc WaitH1 ; retrace
WaitE1:
mov ax,bx
stosw
sti
pop bx ; restore
pop dx ; restore
col2: pop es ; restore
pop di ; restore
pop ax ; restore
popf ; restore flags
iret ; done
;
route_video_exit:
jmp video_exit
;
read_cursor:
cmp bh,cs:active_page ; check page
jne route_video_exit ; pass to bios
push di ; save
push es ; save
les di,cs:bios_cursor_posn ; get bios
mov dx,es:[di] ; get bios posn
mov cx,cs:cursor_type ; get type
pop es ; restore
pop di ; restore
popf ; restore flags
iret ; done
;
set_page:
push ax ; save
mov cs:active_page,al ; save page
xor ah,ah ; page in ax
shl ax,1 ; for word count
add ax,50h ; offset for page zero
mov cs:bios_ofst,ax ; save offset
pop ax ; restore
jmp video_exit ; pass to bios
;
set_type:
mov cs:cursor_type,cx ; save type
jmp video_exit ; pass to bios
;
set_mode:
mov cs:crt_mode,al ; save mode
mov cs:video_ofst,0 ; top left
jmp video_exit ; done
;
TTY:
cmp bh,cs:active_page ; check page
jne route_video_exit ; pass to bios
cmp al,' ' ; control characters
jb TTY_std ; go to real BIOS
cmp cs:video_ofst,25*80*2-2 ; scroll imminent ?
jnb TTY_std ; yes, to real BIOS
push ax ; save
push cx ; save
push dx ; save
push di ; save
push es ; save
push ax
les di,cs:bios_cursor_posn
mov ax,es:[di]
mov cx,ax ; copy posn
mov al,ah ; rows in al
mul cs:onesixty ; for bytes
xor ch,ch ; cols in cx
shl cx,1 ; for video
add ax,cx ; offset in ax
mov cs:video_ofst,ax ; store offset
pop ax
les di,cs:video_posn ; get screen pos
cmp cs:flag,1 ; Snow checking?
je tty0
stosb
jmp tty1
tty0: push dx
mov dx,03DAh
xchg ah,al
cli
WaitNoH2:
in al, dx ; Get 6845 Status
test al,8 ; Check vert retrace
jnz WaitE2 ; In Progress? go
rcr al,1 ; Wait for end of
jc WaitNoH2 ; horizontial retrace
WaitH2:
in al, dx ; Get 6845 status again
rcr al, 1 ; Wait for horizontial
jnc WaitH2 ; retrace
WaitE2:
xchg ah,al
stosb
sti
pop dx
tty1: les di,cs:bios_cursor_posn ; get bios
mov dx,es:[di] ; get current pos
inc dl ; next char pos
cmp dl,79 ; new line ?
ja TTY_new_line ; yes, adjust
jmp set_cursor_2 ; set cursor
TTY_new_line:
mov dl,0 ; col = 1
inc dh ; inc row
jmp set_cursor_2 ; set cursor
TTY_std:
pushf ; phony int
call cs:video_vector ; to real bios
push ax ; save
push bx ; save
push es ; save
les di,cs:bios_cursor_posn
mov ax,es:[di]
mov cx,ax ; copy posn
mov al,ah ; rows in al
mul cs:onesixty ; for bytes
xor ch,ch ; cols in cx
shl cx,1 ; for video
add ax,cx ; offset in ax
mov cs:video_ofst,ax ; store offset
pop es ; restore
pop bx ; restore
pop ax ; restore
popf ; restore flags
iret ; done
;
; remove routine from memory
;
do_kill:
mov ax,cs ; get code segment
mov ds,ax ; set data segment
mov es,ax ; set extra segment
push ds ; save
mov ax,2510h ; to set video vector
lds dx,video_vector ; get original
int 21h ; set vector
pop ds ; restore
mov ah,49h ; for free memory fn
int 21h ; do free memory
push es ; save
mov bx,environment ; get env. segment
mov es,cs:[bx]
mov ah,49h ; for free memory fn
int 21h ; do free memory
pop es ; restore
lea dx,kill_msg ; get message
mov ah,9 ; for screen write
int 21h ; do write
popf ; restore flags
iret ; return to ZENO/K
;
kill_msg db 13,10,'ZENO Removed',13,10,'$'
;
end_core:
;
;-------------------------------
; enter here to load program
;-------------------------------
;
load_pgm:
;
; check for color screen; set video segment
;
mov video_seg,0B000h ; assume mono
mov video_addr,03B4h ; assume mono
int 11h ; for equip check
and ax,30h ; isolate adapter
cmp ax,30h ; check for mono
je mono_screen ; go if found
mov video_seg,0B800h ; reset for color
mov video_addr,03D4h ; reset for color
mono_screen:
;
; check command line
;
mov si,command ; get command line
mov al,cs:[si] ; length of argument
or al,al ; check for zero
je command_clear ; go if zero
cmp al,2 ; for kill request
jne retry ; go if not
cmp word ptr cs:[si+1],slashs2 ; check for '/s'
je flake
cmp word ptr cs:[si+1],slashs ; check for '/S'
je flake
cmp word ptr cs:[si+1],slashk2 ; check for '/k'
je killme ; go if not
cmp word ptr cs:[si+1],slashk ; check for '/K'
jne retry ; go if not
killme: mov ax,0FEFEh ; set for kill (FORMERLY 0FFOOh)
int 10h ; order kill
int 20h ; exit to DOS
retry:
lea dx,retry_msg ; get message
mov ah,9 ; for print fn
int 21h ; print message
int 20h ; exit to DOS
flake: inc cs:flag ; turn on snow checking
command_clear:
;
; find and set current variables
;
les di,bios_cursor_posn ; set to 0040:0000
mov al,es:[di+49h] ; get current mode
mov crt_mode,al ; save mode
mov ax,es:[di+60h] ; get cursor type
mov cursor_type,ax ; save type
mov al,es:[di+62h] ; get active page
mov active_page,al ; save active page
xor ah,ah ; page in ax
shl ax,1 ; for word count
add ax,50h ; offset for page zero
mov bios_ofst,ax ; save offset
;
; set video interrupt
;
mov core_seg,cs ; set core segment
push es ; save
mov ax,3510h ; to get vector
int 21h ; get vector
mov word ptr video_vector,bx ; store offset
mov word ptr video_vector+2,es ; store segment
pop es ; restore
mov ax,2510h ; to set video vector
lea dx,video_int ; get offset; ds OK
int 21h ; set vector
;
; print messages; terminate and stay resident
;
lea dx,install_msg ; get message
mov ah,9h ; for print fn
int 21h ; print message
cmp cs:flag,1 ; check for snow flag
jne seemon
lea dx,snow_msg ; get message
jmp shmsg ; show message
seemon: cmp video_seg,0B000h ; check for mono
je skip_message ; go if mono
lea dx,color_msg ; get message
shmsg: mov ah,9h ; for print fn
int 21h ; print message
skip_message:
lea dx,finish_msg ; get termination
mov ah,9h ; for print fn
int 21h ; print ternination
lea ax,end_core ; last address in core
add ax,2Fh ; make bumper
mov cl,4 ; for shift
shr ax,cl ; convert to paras
mov bx,ax ; no. paras to keep
mov dx,ax ; same
mov ah,4Ah ; for setblock
int 21h ; do setblock
mov ax,3100h ; for keep; no exit code
int 21h ; exit and stay resident
;
install_msg db 13,10,'ZENO 2.1 successfully Installed!',13,10,'$'
snow_msg db 13,10,'Snow checking enabled.',13,10,'$'
color_msg db 'If snow is present, re-install using the /S option.',13,10
finish_msg db 13,10,'$'
;
retry_msg db 13,10,'No Action: Use /S or /K only!',13,10,7,'$'
;
zeno endp
cseg ends
end start